<template>
    <div class="layer layer-image" :class="{active: active,notify:imageDpi<75}">
        <div class="layer-content">
            <!-- 图片内容 -->
            <div class="layer-info">
                <figure>
                    <img crossOrigin="anonymous" :style="$fiexImage(layer.w,layer.h,1)" :src="getImagePreview(layer.url)" />
                </figure>
                <h2>
                    <strong v-text="layer.name"></strong>
                    <span v-show="imageDpi >= 150" style="color:#23B98F">High resolution</span>
                    <span v-show="imageDpi < 150 && imageDpi >= 75" style="color: #EDB002;">Medium resolution</span>
                    <span v-show="imageDpi < 75" style="color: #F44336;">Low resolution</span>
                </h2>
                <div class="handle" @click="setActive(layer)"></div>
                <div class="layer-info-button">
                    <slot></slot>
                </div>
            </div>

            <!-- 图片因数 -->
            <div class="layer-factor">

                <!-- 位置大小 -->
                <div class="factor-input">
                    <UxInputNumber name="Scale" unit="%" v-model="layerScale" :step="0.1" :precision="2" :min="0" :max="1000" />
                    <UxInputNumber name="Rotate" unit="deg" v-model="layerRotate" :step="1" :min="-360" :max="360" />
                    <UxInputNumber name="Right" unit="%" v-model="layerLeft" :step="0.1" :precision="2" :min="layerRange.minX" :max="100" />
                    <UxInputNumber name="Down" unit="%" v-model="layerTop" :step="0.1" :precision="2" :min="layerRange.minY" :max="100" />
                </div>

                <!-- 对齐 -->
                <div class="factor-align">
                    <button @click="setAlign('left')" title="Left align">
                        <svg-icon name="tooler-left" />
                    </button>
                    <button @click="setAlign('center')" title="Horizontal center align">
                        <svg-icon name="tooler-center" />
                    </button>
                    <button @click="setAlign('right')" title="right align">
                        <svg-icon name="tooler-right" />
                    </button>
                    <button @click="setAlign('top')" title="Top align">
                        <svg-icon name="tooler-top" />
                    </button>
                    <button @click="setAlign('middle')" title="Vertical center align">
                        <svg-icon name="tooler-middle" />
                    </button>
                    <button @click="setAlign('bottom')" title="Bottom align">
                        <svg-icon name="tooler-bottom" />
                    </button>
                </div>

                <!-- 翻转 -->
                <div class="factor-flip">
                    <button @click="setTypes('hor')" :class="{active:layer.flipX}" title="Flip horizontal">
                        <svg-icon name="tooler-fliphor" />
                    </button>
                    <button @click="setTypes('ver')" :class="{active:layer.flipY}" title="Flip vertical">
                        <svg-icon name="tooler-flipver" />
                    </button>

                    <button></button>
                    <button></button>
                    <button></button>

                    <button @click="setTypes('reset')">
                        <svg-icon name="tooler-reset" />
                    </button>
                </div>

            </div>
        </div>

    </div>
</template>

<script>
import DesignResource from "@/utils/DesignResource.js";
export default {
    props: {
        mapper: { type: Object, required: true },
        piece: { type: Object, required: true },
        layer: { type: Object, required: true },
        active: { type: Boolean, required: true },
    },
    data () {
        return {
        };
    },

    computed: {

        // 设计区旋转角度
        mapperRotate () {
            // return this.mapper.rotate || 0
            return 0
        },

        // 设计区大小
        pieceSize () {

            const piece = this.piece;

            const x1 = -piece.canvas_width;
            const y1 = piece.canvas_height;
            const x2 = piece.canvas_width;
            const y2 = piece.canvas_height;
            const rotate = this.mapperRotate || 0;
            const θ = (360 - rotate) * Math.PI / 180;

            const w1 = Math.abs(x1 * Math.cos(θ) - y1 * Math.sin(θ));
            const w2 = Math.abs(x2 * Math.cos(θ) - y2 * Math.sin(θ));
            const h1 = Math.abs(x1 * Math.sin(θ) + y1 * Math.cos(θ));
            const h2 = Math.abs(x2 * Math.sin(θ) + y2 * Math.cos(θ));

            return {
                width: Math.max(w1, w2),
                height: Math.max(h1, h2),
            }
        },
        // 图层大小
        layerSize () {
            const piece = this.piece;
            const layer = this.layer;

            const x1 = -layer.w;
            const y1 = layer.h;
            const x2 = layer.w;
            const y2 = layer.h;
            const rotate = this.mapperRotate || 0;
            const θ = (360 - rotate - layer.rotate) * Math.PI / 180;

            const w1 = Math.abs(x1 * Math.cos(θ) - y1 * Math.sin(θ));
            const w2 = Math.abs(x2 * Math.cos(θ) - y2 * Math.sin(θ));
            const h1 = Math.abs(x1 * Math.sin(θ) + y1 * Math.cos(θ));
            const h2 = Math.abs(x2 * Math.sin(θ) + y2 * Math.cos(θ));

            return {
                width: Math.max(w1, w2),
                height: Math.max(h1, h2),
            }
        },
        imageDpi () {
            const now_dpi = 300; // 当前dpi
            const piece = this.piece;
            const layer = this.layer;

            if (!piece) {
                return 0;
            } else if (!layer) {
                return 0;
            } else {
                const scale = Math.max(piece.real_width / piece.canvas_width, piece.real_height / piece.canvas_height);
                const realW = layer.w * scale;
                const realH = layer.h * scale;
                return Math.min(layer.cutW / realW, layer.cutW / realW) * now_dpi;
            }
        },
        layerScale: {
            get () {
                // 图片旋转之后的宽高
                // 100缩放是指图片旋转之后的宽高相对于容器旋转之后的宽高比例
                const pieceSize = this.pieceSize;
                const layerSize = this.layerSize;
                const scale = Math.max(layerSize.width / pieceSize.width, layerSize.height / pieceSize.height);

                return scale * 100;
            },
            set (value) {
                if (this.layerScale != value) {
                    // 适应容器时，图片的缩放比例
                    const layer = this.layer;
                    const pieceSize = this.pieceSize;

                    // 计算最大长度
                    const x1 = -layer.cutW;
                    const y1 = layer.cutH;
                    const x2 = layer.cutW;
                    const y2 = layer.cutH;
                    const rotate = this.mapperRotate || 0;
                    const θ = (360 - rotate - layer.rotate) * Math.PI / 180;

                    const w1 = Math.abs(x1 * Math.cos(θ) - y1 * Math.sin(θ));
                    const w2 = Math.abs(x2 * Math.cos(θ) - y2 * Math.sin(θ));
                    const h1 = Math.abs(x1 * Math.sin(θ) + y1 * Math.cos(θ));
                    const h2 = Math.abs(x2 * Math.sin(θ) + y2 * Math.cos(θ));

                    // 按图片宽高来算的长度
                    const width = Math.max(w1, w2);
                    const height = Math.max(h1, h2);

                    // 修改后的缩放比例
                    const scale = Math.max(width / pieceSize.width, height / pieceSize.height);

                    const w = layer.cutW * 0.01 * value / scale;
                    const h = layer.cutH * 0.01 * value / scale;
                    const x = Math.round(this.layer.x + (this.layer.w - w) / 2);
                    const y = Math.round(this.layer.y + (this.layer.h - h) / 2);
                    const change = { w: w, h: h, x: x, y: y }

                    this.$emit('dispatch:updateLayer', { type: 'update', layer: layer, change: change });
                }
            }
        },
        layerRotate: {
            get () {
                return this.layer.rotate + this.mapperRotate;
            },
            set (value) {
                const rotate = value - this.mapperRotate;
                const format = parseInt((180 + rotate) % 360 - 180) || 0;
                const change = { rotate: format }

                this.$emit('dispatch:updateLayer', { type: 'update', layer: this.layer, change: change });

            }
        },

        layerRange () {
            const piece = this.piece;
            const layer = this.layer;
            const w = piece.canvas_width || 1;
            const h = piece.canvas_height || 1;

            return {
                minX: - 100 * layer.w / w,
                minY: - 100 * layer.h / h,
            }

        },
        layerLeft: {
            get () {
                const layer = this.layer;
                const piece = this.piece;

                const pieceSize = this.pieceSize;
                const layerSize = this.layerSize;

                const θ = (360 + this.mapperRotate) * Math.PI / 180;
                const xc = layer.x + 0.5 * layer.w - 0.5 * piece.canvas_width;
                const yc = layer.y + 0.5 * layer.h - 0.5 * piece.canvas_height;
                const x = xc * Math.cos(θ) - yc * Math.sin(θ);

                return 100 * (0.5 * pieceSize.width + x - 0.5 * layerSize.width) / pieceSize.width

            },
            set (value) {

                if (this.layerLeft != value) {

                    const left = value;
                    const top = this.layerTop;

                    const layer = this.layer;
                    const piece = this.piece;

                    const pieceSize = this.pieceSize;
                    const layerSize = this.layerSize;

                    const θ = (360 - this.mapperRotate) * Math.PI / 180;

                    const xc = 0.01 * left * pieceSize.width + 0.5 * layerSize.width - 0.5 * pieceSize.width;
                    const yc = 0.01 * top * pieceSize.height + 0.5 * layerSize.height - 0.5 * pieceSize.height;

                    const x1 = xc * Math.cos(θ) - yc * Math.sin(θ);
                    const y1 = xc * Math.sin(θ) + yc * Math.cos(θ);

                    const change = {
                        x: x1 - 0.5 * layer.w + 0.5 * piece.canvas_width,
                        y: y1 - 0.5 * layer.h + 0.5 * piece.canvas_height,
                    }

                    this.$emit('dispatch:updateLayer', { type: 'update', layer: layer, change: change });

                }
            }
        },
        layerTop: {
            get () {

                const layer = this.layer;
                const piece = this.piece;
                const mapper = this.mapper

                const pieceSize = this.pieceSize;
                const layerSize = this.layerSize;

                const θ = (360 + this.mapperRotate) * Math.PI / 180;
                const xc = layer.x + 0.5 * layer.w - 0.5 * piece.canvas_width;
                const yc = layer.y + 0.5 * layer.h - 0.5 * piece.canvas_height;
                const y = xc * Math.sin(θ) + yc * Math.cos(θ);

                return 100 * (0.5 * pieceSize.height + y - 0.5 * layerSize.height) / pieceSize.height;

            },
            set (value) {

                if (this.layerTop != value) {

                    const left = this.layerLeft;
                    const top = value;

                    const layer = this.layer;
                    const piece = this.piece;
                    const mapper = this.mapper

                    const pieceSize = this.pieceSize;
                    const layerSize = this.layerSize;

                    const θ = (360 - this.mapperRotate) * Math.PI / 180;

                    const xc = 0.01 * left * pieceSize.width + 0.5 * layerSize.width - 0.5 * pieceSize.width;
                    const yc = 0.01 * top * pieceSize.height + 0.5 * layerSize.height - 0.5 * pieceSize.height;

                    const x1 = xc * Math.cos(θ) - yc * Math.sin(θ);
                    const y1 = xc * Math.sin(θ) + yc * Math.cos(θ);

                    const change = {
                        x: x1 - 0.5 * layer.w + 0.5 * piece.canvas_width,
                        y: y1 - 0.5 * layer.h + 0.5 * piece.canvas_height,
                    }

                    this.$emit('dispatch:updateLayer', { type: 'update', layer: layer, change: change });
                }
            }
        },

    },

    methods: {
        // 对齐方式
        setAlign (type) {

            const pieceSize = this.pieceSize;
            const layerSize = this.layerSize;

            if (type == 'left') {
                // 水平居左
                this.layerLeft = 0;
            } else if (type == 'center') {
                // 水平居中
                this.layerLeft = 50 * (pieceSize.width - layerSize.width) / pieceSize.width;
            } else if (type == 'right') {
                // 水平居右
                this.layerLeft = 100 * (pieceSize.width - layerSize.width) / pieceSize.width;
            } else if (type == 'top') {
                // 垂直居上
                this.layerTop = 0;
            } else if (type == 'middle') {
                // 垂直居中
                this.layerTop = 50 * (pieceSize.height - layerSize.height) / pieceSize.height;
            } else if (type == 'bottom') {
                // 垂直居下
                this.layerTop = 100 * (pieceSize.height - layerSize.height) / pieceSize.height;
            }
        },

        // 排版
        setTypes (type) {
            const layer = this.layer;
            if (type == 'hor') {
                this.$emit('dispatch:updateLayer', { type: 'update', layer: layer, change: { flipX: !layer.flipX } });
            } else if (type == 'ver') {
                this.$emit('dispatch:updateLayer', { type: 'update', layer: layer, change: { flipY: !layer.flipY } });
            } else if (type == 'tiled') {
                // 平铺
            } else if (type == 'reset') {
                // 重置
                this.$emit('dispatch:updateLayer', { type: 'reset', layer: layer });
            }
        },

        // 选中
        setActive (layer) {
            if (this.active) {
                this.$emit('dispatch:updateLayer', { type: 'active', layer: null });
            } else {
                this.$emit('dispatch:updateLayer', { type: 'active', layer: layer });
            }
        },

        getImagePreview (url) {
            let cache = DesignResource.getImageByCache(url, { type: "simple", form: "materials" })
            if (cache) {
                return cache.src;
            } else {
                this.$getLitimgUrl(url, 'medium')
            }
        },
    },

};
</script>

<style lang="scss" scoped>
.factor-custom {
    display: flex;
    flex-direction: row;
    justify-content: flex-end;
    position: relative;
    padding: 14px 0 0;
    border-top: 1px solid #f0f0f0;
    margin: 0 18px;

    > button {
        position: relative;
        width: 184px;
        height: 40px;
        border-radius: 6px;
        font-size: 14px;
        font-weight: 600;
        line-height: 16px;
    }
    span {
        background: none;
        display: none;
        &:nth-child(1) {
            display: inline;
        }
    }
}
</style>